﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DocumentFormat.OpenXml.Lite.Helper;
using DocumentFormat.OpenXml.Lite.Core.DocumentFS;
using System.Xml.Serialization;
using IO = System.IO;
using DocumentFormat.OpenXml.Lite.Core.Office;
using DocumentFormat.OpenXml.Lite.Core.Interfaces;

namespace DocumentFormat.OpenXml.Lite.Core.Relationship
{
    [XmlRoot("Relationships")]
    public class RelationshipManager : ISerializable
    {
        [XmlElement("Relationship")]
        public List<Relationship> RelationshipTags { get; set; }

        [XmlNamespaceDeclarations]
        public XmlSerializerNamespaces Namespaces { get; set; }

        [XmlIgnore]
        private int nextId = 1;

        public RelationshipManager()
        {
            RelationshipTags = new List<Relationship>();

            Namespaces = new XmlSerializerNamespaces();
            Namespaces.Add(string.Empty, URI.Relationships.GetDescription());
        }

        public int CreateRelationship(RelationshipURI type, File target)
        {
            RelationshipTags.Add(new Relationship()
            {
                Type = type.GetDescription(),
                Target = target.GetXmlPath(),
                Id = "rId" + (nextId++).ToString()
            });
            return nextId - 1;
        }

        public int CreateRelationship(RelationshipURI type, File target, Directory relativeTo)
        {
            RelationshipTags.Add(new Relationship()
            {
                Target = DocumentFS.Directory.Combine(target, relativeTo),
                Type = type.GetDescription(),
                Id = "rId" + (nextId++).ToString()
            });
            return nextId - 1;
        }

        public static string GetRelationshipId(int id)
        {
            return "rId" + id.ToString();
        }

        #region ISerializable members

        public byte[] Serialize()
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType(), URI.Relationships.GetDescription());
            using (var stream = new IO.MemoryStream())
            {
                using (var writer = new IO.StreamWriter(stream, Encoding.UTF8))
                {
                    serializer.Serialize(writer, this, Namespaces);
                    return stream.ToArray();
                }
            }
        }

        public void Deserialize(System.IO.Stream content)
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType(), URI.Relationships.GetDescription());
            var rm = serializer.Deserialize(content) as RelationshipManager;

            this.RelationshipTags = rm.RelationshipTags;

            var supportedTags = Enum.GetValues(typeof(RelationshipURI)).Cast<RelationshipURI>().Select(e => e.GetDescription());
            this.RelationshipTags.Where(t => !supportedTags.Contains(t.Type)).ToList().ForEach(t => this.RelationshipTags.Remove(t));
        }

        #endregion
    }
}
